package com.wxtech.heartbeat.server.protocol;

import java.nio.ByteBuffer;
import java.util.Date;

import org.apache.log4j.Logger;

import com.wxtech.heartbeat.model.ErrorData;
import com.wxtech.heartbeat.util.Checksum;
import com.wxtech.heartbeat.util.DateUtil;
import com.wxtech.heartbeat.util.IntegerUtil;

import io.netty.buffer.ByteBuf;

public abstract class Protocol {
	private static Logger logger = Logger.getLogger(Protocol.class);
//	public static final byte DELIMITER = (byte )0x16;	
//	public static final int REPLY_CODE_FAILURE = 0x01;
	public static final int MIN_BYTE_NUMBER = 18;//暂定, just header
	public static final String INVALID_CMD_HEX = "FF";
	
	
	
//	protected static String CMD_TYPE_HEX = "00";
	

	
	
	public abstract DecodeResult decode(ByteBuf buffer);
	
	public abstract boolean isBufferDataEnough(ByteBuf buffer);

//	public static String getCmdTypeHex() {
//		return "00";
//	}
	
	//一些公有函数

	public static DecodeResult buildErrorResult(String msg,
			int code, byte[] raw) {
		ErrorDecodeResult edr = new ErrorDecodeResult();
		edr.setErrorMessage(msg);
		edr.setErrorCode(code);
		edr.setRawData(raw);
		return edr;
	}
	
	public static ErrorData buildError(byte[] raw, int errorCode) {
//		buffer.readBytes(raw);
		ErrorData errorData = new ErrorData();
		errorData.setErrorCode(errorCode);
		errorData.setData(raw);
		return errorData;
	}

	public static boolean compareCrc(byte[] data, int receivedCrc) {
		ByteBuffer bb = ByteBuffer.wrap(data);
		int crc16 = Checksum.crc16(Checksum.CRC16_AUG_CCITT, bb);
		logger.debug("computed crc =" + crc16);
		return crc16 == receivedCrc;
		
	}
	
	public static String getU64(ByteBuf buffer, int begin) {
		byte[] tmp = new byte[8];
		buffer.getBytes(begin, tmp);
		String u64 = IntegerUtil.parseU64(tmp);
		return u64;
	}
	
	/**
	 * 6 byte, year u8, month u8, day u8, hour u8
	 * min u8, second u8
	 * the year will be 2017 - 1970. we need to add it back
	 * @param buffer
	 * @param begin
	 * @return
	 */
	public static Date getFormalDate(ByteBuf buffer, int begin) {
		byte[] tmp = new byte[6];
		buffer.getBytes(begin, tmp);
		Date beatDate = DateUtil.parseDateTime(tmp);
		return beatDate;
	}

}
